/**
 * Beschreiben Sie hier die Klasse Steuerung.
 * 
 * @author christoph.stueber@mes-alsfeld.de
 * @version Schuljahr 2013/2014 geändert 14.03.2014 erstellt 14.03.2014
 */
public class Steuerung
{
    /** */
    public static final int WKAZAHL = 8;

    /** */
    private int wkaStatus;

    /** */
    private int aktuellLaufendeWKA;

    /** */
    private Windmessung eineWindmessung;

    /** */
    private Stoerungsmeldung eineStoerungsmeldung;

    /** Ports zur Messdatenerfassung */
    IOPorts ports = new IOPorts();

    /** die Windkraftanlagen der Steuerung. */
    private WKA[] windkraftanlagen = new WKA[WKAZAHL];

    /** Ereignisse */
    private Liste<Ereignis> ereignisse = new Liste<Ereignis>();

    /**
     * Konstruktor zum Erzeugen von Objekten der Klasse Steuerung.
     */
    public Steuerung()
    {
        ports = new IOPorts();
        for (int i = 0; i < WKAZAHL; i++)
        {
            windkraftanlagen[i] = new WKA(i + 1);

        }
        eineStoerungsmeldung = new Stoerungsmeldung(this);
        eineStoerungsmeldung.start();
        eineWindmessung = new Windmessung(this);
        eineWindmessung.start();
    }

    /**
     * Accessor für ports
     */
    public IOPorts getPorts()
    {
        return ports;
    }

    /**
     * Accessor für Ereignisse.
     * 
     * @return <Ereignis>Liste
     */
    public Liste<Ereignis> getEreignisse()
    {
        return ereignisse;
    }

    /**
     * Accessor für windkraftanlagen.
     * 
     * @return WKA[]
     */
    public WKA[] getWindkraftanlagen()
    {
        return windkraftanlagen;
    }

    /**
     * schalten-Methode.
     */
    public void schalten(int windstufe)
    {
        if (windstufe == 1 || windstufe == 4)
        {
            for (WKA w : windkraftanlagen)
            {
                w.ausschalten();
            }
            aktuellLaufendeWKA = 0;
            wkaStatus = 0;
        }
        else if (windstufe == 2)
        {
            for (int i = 0; i < WKAZAHL; i++)
            {
                if (!windkraftanlagen[i].istGesperrt()
                        && !windkraftanlagen[i].istEingeschaltet())
                {
                    windkraftanlagen[i].einschalten();
                    wkaStatus = wkaStatus | (1 << i);
                    aktuellLaufendeWKA++;
                }
            }
        }
        else
        // windstufe ==3
        {
            if (aktuellLaufendeWKA == 0)
            {
                int i = 0;
                while ((i < WKAZAHL) && (aktuellLaufendeWKA < 5))
                {
                    if (!windkraftanlagen[i].istGesperrt())
                    {
                        windkraftanlagen[i].einschalten();
                        wkaStatus = wkaStatus | (1 << i);
                        aktuellLaufendeWKA++;
                    }

                }
            }
            else
            {
                int i = 0;
                while ((i < WKAZAHL) && (aktuellLaufendeWKA > 5))
                {
                    if (windkraftanlagen[i].istEingeschaltet())
                    {
                        windkraftanlagen[i].ausschalten();
                        wkaStatus = wkaStatus & ~(1 << i);
                        aktuellLaufendeWKA--;
                    }
                    i++;
                }

            }
        }
        ereignisse.add(new Ereignis(wkaStatus, windstufe));
    }

    /**
     * behandleStoerung-Methode.
     * 
     * @param WKANr int
     */
    public synchronized void behandleStoerung(int wkaNr)
    {
        windkraftanlagen[wkaNr - 1].sperren();
        windkraftanlagen[wkaNr - 1].ausschalten();
        wkaStatus = (wkaStatus & ~(1 << (wkaNr - 1)));
        aktuellLaufendeWKA--;
        if (aktuellLaufendeWKA <= 4)
        {
            for (WKA w : windkraftanlagen)
            {
                if (!w.istEingeschaltet() && !w.istGesperrt())
                {
                    w.einschalten();
                    wkaStatus = (wkaStatus | (1 << (wkaNr - 1)));
                    aktuellLaufendeWKA++;
                    break;
                }
            }
        }
        ports.writeDigital(wkaStatus);
        int stufe = eineWindmessung.getWindstufe();
        WKA w = windkraftanlagen[wkaNr - 1];
        ereignisse.add(new Stoerung(w, wkaStatus, stufe));
    }

    public String getMessage()
    {
        String s = "";
        Date datum = new Date();
        for (Ereignis e : getEreignisse())
        {
            s += "\n" + datum.getDate() + " um " + datum.getTime();
            s += " Windstufe: " + e.getWindstufe();
            int status = e.getWkaStatus();
            s += "\nLaufend WKAs: Nr. " + status + " ";
            for (int i = 0; i < Steuerung.WKAZAHL; i++)
            {
                if ((status & (1 << i)) > 0)
                {
                    s += (i + 1) + " ";
                }
            }
        }
        return s;
    }

    /**
     * Methode zum Beenden der Steuerung, beendet alle laufende Threads.
     */
    public void beenden()
    {
        eineWindmessung.beenden();
        eineStoerungsmeldung.beenden();
    }

}
